package org.liurb.springboot.starter.web.mvc.filter;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.ContentType;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.liurb.springboot.starter.web.mvc.filter.dto.CachedBodyHttpServletRequest;
import org.springframework.web.util.ContentCachingResponseWrapper;

import java.io.IOException;

/**
 * 公共过滤器
 *
 * 子项目继承此过滤器即可实现request流可重复读
 *
 * @Author Liurb
 * @Date 2022/11/28
 */
public abstract class BackendHttpServletRequestFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper((HttpServletResponse) response);

        try {

            HttpServletRequest httpRequest = (HttpServletRequest) request;

            String contentType = httpRequest.getContentType();

            if (StrUtil.isNotBlank(contentType) && contentType.contains(ContentType.MULTIPART.getValue())) {//不处理multipart/form-data类型的请求流复制

                doFilterMore(request, response, chain);

                chain.doFilter(request, responseWrapper);

            } else {

                CachedBodyHttpServletRequest cachedBodyHttpServletRequest =
                        new CachedBodyHttpServletRequest((HttpServletRequest) request);

                doFilterMore(request, response, chain);

                chain.doFilter(cachedBodyHttpServletRequest, responseWrapper);

            }

        } finally {

            responseWrapper.copyBodyToResponse();

        }
    }

    /**
     * 提供一个方法可以对请求进行更多的过滤操作
     *
     * 返回false过滤拦截
     *
     * @param request
     * @param response
     * @param chain
     */
    public abstract void doFilterMore(ServletRequest request, ServletResponse response, FilterChain chain);

}
